﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.ServiceModel.Activation;
using System.Web.Mvc;
using System.Web.Http;

using Microsoft.Practices.Unity;

using ERPStore.Extensions;
using ERPStore.Web.Routing;

namespace ERPStore.Offers
{
	public class PluginInit : ERPStore.Extensibility.PluginInit
	{
		public PluginInit()
		{
			Container = GlobalConfiguration.Configuration.DependencyResolver.GetContainer();
		}

		Microsoft.Practices.Unity.IUnityContainer Container { get; set; }

		public override void AddServices()
		{
			var settings = new Models.Settings();
			settings.BindFromConfiguration(Configuration.ConfigurationSettings.AppSettings);
			Container.RegisterInstance(settings);

			if (settings.RepositoryName == "mock")
			{
				Container.RegisterType<CloudSoft.Repositories.IRepository<Repositories.OffersDbContext>, CloudSoft.Repositories.MemoryRepository<ERPStore.Offers.Repositories.OffersDbContext>>(new ContainerControlledLifetimeManager());
			}
			else
			{
				Container.RegisterType<CloudSoft.Repositories.IDbContextFactory<Repositories.OffersDbContext>, CloudSoft.Repositories.DbContextFactory<Repositories.OffersDbContext>>();
				Container.RegisterType<CloudSoft.Repositories.IRepository<Repositories.OffersDbContext>,CloudSoft.Repositories.SqlRepository<Repositories.OffersDbContext>>();
				Container.RegisterType<CloudSoft.Repositories.IRepositoryInitializer, CloudSoft.Repositories.Initializers.SqlSchemaInitializer<Repositories.OffersDbContext>>("offerssqlschemainitializer", new PerResolveLifetimeManager());
			}

			Container.RegisterType<ERPStore.Services.IOffersService, Services.OffersService>();
			Container.RegisterType<Services.AdminOffersService>();

			// Validators
			Container.RegisterType<global::FluentValidation.IValidator<Models.OfferEx>, ModelValidators.OfferValidator>("Validator:" + typeof(Models.OfferEx).FullName, new ContainerControlledLifetimeManager());
			Container.RegisterType<global::FluentValidation.IValidator<Models.OfferedProduct>, ModelValidators.OfferedProductValidator>("Validator:" + typeof(Models.OfferedProduct).FullName, new ContainerControlledLifetimeManager());

			// Mapping
			AutoMapper.Mapper.CreateMap<Repositories.Datas.OfferData, Models.OfferEx>();
			AutoMapper.Mapper.CreateMap<Models.OfferEx, Repositories.Datas.OfferData>();

			AutoMapper.Mapper.CreateMap<Repositories.Datas.OfferedProductData, Models.OfferedProduct>()
				.ForMember(dest => dest.FixedShippingPrice, opt => opt.MapFrom(origin => origin.FixedShippingPrice.HasValue ? origin.FixedShippingPrice.Value / 1000000.0m : new Nullable<decimal>()))
				.ForMember(dest => dest.Discount, opt => opt.MapFrom(origin => origin.Discount.HasValue ? origin.Discount.Value / 1000000.0m : new Nullable<decimal>()))
				.ForMember(dest => dest.SalePrice, opt => opt.MapFrom(origin => origin.SalePrice.HasValue ? origin.SalePrice.Value / 1000000.0m : new Nullable<decimal>()));

			AutoMapper.Mapper.CreateMap<Models.OfferedProduct, Repositories.Datas.OfferedProductData>()
				.ForMember(dest => dest.FixedShippingPrice, opt => opt.MapFrom(origin => origin.FixedShippingPrice.HasValue ? Convert.ToInt64(origin.FixedShippingPrice.Value * 1000000) : new Nullable<long>()))
				.ForMember(dest => dest.Discount, opt => opt.MapFrom(origin => origin.Discount.HasValue ? Convert.ToInt64(origin.Discount.Value * 1000000) : new Nullable<long>()))
				.ForMember(dest => dest.SalePrice, opt => opt.MapFrom(origin => origin.SalePrice.HasValue ? Convert.ToInt64(origin.SalePrice.Value * 1000000) : new Nullable<long>()));
		}

		public override void Load()
		{
			var settings = Container.Resolve<Models.Settings>();
			if (settings.RepositoryName != "mock")
			{
				var initializer = Container.Resolve<CloudSoft.Repositories.IRepositoryInitializer>("offerssqlschemainitializer");
				if (initializer != null)
				{
					initializer.Initialize("_erpstore_schema_offers");
				}
			}
		}

		public override void RegisterRoutes()
		{
			var namespaces = new string[] { "ERPStore.Offers.Controllers" };

			RouteTable.Routes.MapERPStoreRoute(
				"OfferProduct"
				, "offre/{code}/{*productLink}"
				, new { controller = "Offers", action = "Product", code = string.Empty, productLink = string.Empty }
			);

			RouteTable.Routes.MapERPStoreRoute(
				"OfferLink"
				, "offres/{*offerLink}"
				, new { controller = "Offers", action = "Offer", offerLink = string.Empty }
				, namespaces
			);

			var offerService = Container.Resolve<Services.AdminOffersService>();
			var offerList = offerService.GetCurrentOffers();
			if (offerList != null)
			{
				foreach (var offer in offerList)
				{
					RouteTable.Routes.MapERPStoreRoute(
						string.Format("OfferLink.{0}", offer.Id)
						, offer.Link
						, new { controller = "Offers", action = "Offer", offerLink = offer.Link }
						, namespaces
					);
				}
			}

			RouteTable.Routes.MapERPStoreRoute(
				"Offers"
				, "offers/{action}/{id}"
				, new { controller = "Offers", action = "Index", id = UrlParameter.Optional }
				, namespaces
			);

			/*
			var routes = System.Web.Http.GlobalConfiguration.Configuration.Routes;

			routes.MapHttpRoute(
				"AdminOffersApi"
				, "api/adminoffers/{action}/{id}"
				, new { controller = "AdminOffersApi", action = "Ping", id = UrlParameter.Optional }
			);

			routes.MapHttpRoute(
				"OffersApi"
				, "api/offers/{action}/{id}"
				, new { controller = "OffersApi", action = "Ping", id = UrlParameter.Optional }
			);
			 */
		}
	}
}
